#include "downloader.h"
#include <QUrl>
#include <QMessageBox>
#include <QFileInfo>
#include <QTextCodec>

#include <QHttpPart>
#include <QHttpMultiPart>
#include <QDir>
#include <QSettings>

DownLoader::DownLoader(QObject *parent) : QObject(parent)
{
    manager = new QNetworkAccessManager(this);
    file = 0;
    reply = 0;
    overwriteFiles = false;
    empty = false;
    errsite = false;
    siteerrdesc="";
}

DownLoader::~DownLoader()
{
}

///////////////////////PRIVATE SLOTS://////////////////////////////////////////////////
void DownLoader::headersChanged()
{
    if (reply->error()>0)
    {
        errorStr = tr("Network error: %1").arg(QString::number(reply->error()));
        return;
    }
    QByteArray dta = reply->readAll();
    int statuscode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if ((statuscode>=300) && (statuscode<=399))
    {
        redirectLocation = reply->rawHeader(QString("location").toAscii());
        reply->abort();
        return;
    }

    if (reply->hasRawHeader(QString("Content-Disposition").toAscii()))
    {
        QString inf = reply->rawHeader(QString("Content-Disposition").toAscii());
        int startpos = inf.indexOf("filename=", 0, Qt::CaseInsensitive);
        if (startpos>=0)
        {
            int len = inf.length()-startpos-QString("filename=").length();
            if (len>0)
            {
                filename = inf.right(len);
                filename.remove(QChar('\"'));
            }
        }
    }else if (reply->hasRawHeader(QString("error").toAscii())){
        QString errdesc = reply->rawHeader(QString("error").toAscii());
        if(errdesc != "empty")
        {
            errsite = true;
            siteerrdesc = errdesc;
            //emit finished(errorStr, isAborted, isPaused);
            reply->abort();
            return;
        }else{
            empty=true;
            //reply->abort();
            return;
        }
    }

    qint64 size = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong();

    if (!overwriteFiles)
    {
        while (QFile::exists(path+filename))
        {
            filename.append("_1");
        }
    }

    emit started(filename, size, fileurl);
    file = new QFile(path+filename+".part");
    if (!file->open(QIODevice::ReadWrite))
    {
        errorStr = tr("Can 't create file %1").arg(filename);
        reply->abort();
        return;
    }
}

void DownLoader::dataReady()
{
    if(errsite || empty)
    {
        reply->abort();
        return;
    }
    if (reply->error()>0)
    {
        errorStr = tr("Network error: %1").arg(QString::number(reply->error()));
        return;
    }
    QByteArray bytes = reply->readAll();
    if (file->write(bytes)<0)
    {
        errorStr = tr("Error writing file %1").arg(filename);
        reply->abort();
        return;
    }
}

void DownLoader::requestFinished()
{
    if(errsite || empty){
        if (file){
            file->close();
            file->remove();

        }
        emit finished(siteerrdesc, isAborted, isPaused);
        return;
    }

    if (!redirectLocation.isEmpty())
    {
        download(QString(redirectLocation), papka, overwriteFiles);
        return;
    }
    if (reply->error()>0 && (errorStr.isEmpty()))
    {
        errorStr = tr("Network error: %1").arg(QString::number(reply->error()));
    }
    if (file)
    {
        file->close();
        if ((isAborted || (!errorStr.isEmpty())) && (!isPaused))
        {
            file->remove();
        } else
        {
            QString fn = file->fileName();
            fn = fn.mid(0, fn.size()-5);
            file->rename(fn);
        }
        delete file;
    }
    emit finished(errorStr, isAborted, isPaused);
    file = 0;
}

///////////////////////////////////////////////////////////////////////////////////////

//////////////////////PUBLIC SLOTS:////////////////////////////////////////////////////
void DownLoader::download(const QString &username, const QString &password, bool overwrite)
{
    //isFirst = true;
    overwriteFiles = overwrite;
    isAborted = false;
    isPaused = false;
    errorStr.clear();
    redirectLocation.clear();
    empty = false;
    errsite = false;
    siteerrdesc="";
    QUrl url;
    fileurl = "http://192.168.1.9/torchlight/download.php";
    url.setEncodedUrl(fileurl.toAscii());
    if (!url.isValid())
    {
        emit finished(tr("Error: Bad file URL"), isAborted, isPaused);
        return;
    }
    //////filename from url///////////////////////////
    QFileInfo fileinfo(url.path());
    filename = fileinfo.fileName();
    if (filename.isEmpty())
    {
        filename = "index.html";
    }
    path = "tmZip/";

    /////////////////////////////////////////////////////

    QUrl serviceUrl = QUrl(fileurl);
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart p1;
    p1.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"u\""));
    p1.setBody(username.toAscii());
    QHttpPart p2;
    p2.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"p\""));
    p2.setBody(Escape64(password).toAscii());

    multiPart->append(p1);
    multiPart->append(p2);
    reply = manager->post(QNetworkRequest(serviceUrl),multiPart);
    multiPart->setParent(reply);

    connect(reply, SIGNAL(metaDataChanged()), this, SLOT(headersChanged()));
    connect(reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(progress(qint64,qint64)));
    connect(reply, SIGNAL(finished()), this, SLOT(requestFinished()));
}

void DownLoader::cancelDownload()
{
    isAborted = true;
    errorStr = tr("Error: Aborted by user");

    if (reply)
        reply->abort();
}

void DownLoader::pauseDownload()
{
    isPaused = true;
    errorStr = tr("Paused");

    if (reply)
        reply->abort();
}

QString DownLoader::Escape64(QString base)
{
    //'+/=', '-_,');
    base=base.replace('+','-');
    base=base.replace('/','_');
    base=base.replace('=',',');
    return base;
}

///////////////////////////////////////////////////////////////////////////////////////
